<template>
	<van-pull-refresh v-model="main.pullRefresh" @refresh="onRefresh">
		<van-loading type="spinner" :size="usePxToVwView(24)" vertical :style="{ marginTop: usePxToVwView(30) }"
			v-if="main.loading">
			加载中...
		</van-loading>

		<van-collapse v-model="main.activeNames">
			<van-collapse-item title="筛选查询" :name="1">
				<van-row class="queryList">
					<van-col span="6">日期排序</van-col>
					<van-col span="14">
						<van-radio-group v-model="main.queryInfo.travelDateSort" direction="horizontal">
							<van-radio :name="1">升序</van-radio>
							<van-radio :name="0">降序</van-radio>
						</van-radio-group>
					</van-col>
					<van-col span="4" @click="queryTravelDateSort">
						<van-icon name="search" />
						查询
					</van-col>
				</van-row>

				<van-row class="queryList travelDateRange">
					<van-col span="6">日期范围</van-col>
					<van-col span="14">
						<span @click="main.queryInfo.showCalendar = true">
							{{
								main.queryInfo.travelDateRange.length > 1
									? main.queryInfo.travelDateRangeText
									: "请选择日期范围"
							}}
						</span>
						<van-icon class="close" name="close" v-show="main.queryInfo.travelDateRange.length > 1"
							@click.stop="clearTravelDateRange" />
						<van-calendar @touchmove.stop v-model:show="main.queryInfo.showCalendar"
							:min-date="dayjs().subtract(1, 'year').toDate()" :max-date="dayjs().toDate()" :default-date="[
								dayjs().subtract(1, 'day').toDate(),
								dayjs().toDate(),
							]" type="range" @confirm="onCalendarConfirm" />
					</van-col>
					<van-col span="4" @click="handleFilter('date')">
						<van-icon name="search" />
						查询
					</van-col>
				</van-row>

				<van-action-sheet v-model:show="main.showTravelPeopleActionSheet" title="出差人员">
					<div class="action-sheet-content">
						<van-grid :column-num="4" :gutter="10" square>
							<van-grid-item v-for="value in store.PeopleLibrary" :key="value" icon="user-circle-o"
								:text="value" @click="selectTravelPeople(value)" :icon-color="main.queryInfo.peopleName === value ? '#1989fa' : ''
									" :class="{ avtive: main.queryInfo.peopleName === value }">

							</van-grid-item>
						</van-grid>
					</div>
				</van-action-sheet>
				<van-row class="queryList peopleName">
					<van-col span="6">出差人员</van-col>
					<van-col span="14">
						<van-field readonly v-model="main.queryInfo.peopleName" placeholder="出差人员姓名" clearable
							@update:model-value="delPeopleName"
							@click-input="main.showTravelPeopleActionSheet = true" />
					</van-col>
					<van-col span="4" @click="handleFilter('people')">
						<van-icon name="search" />
						查询
					</van-col>
				</van-row>

				<van-action-sheet v-model:show="main.showHandledByActionSheet" title="经办人员">
					<div class="action-sheet-content">
						<van-grid :column-num="4" :gutter="10" square>
							<van-grid-item v-for="value in store.PeopleLibrary" :key="value" icon="user-circle-o"
								:text="value" @click="selectHandledBy(value)" :icon-color="main.queryInfo.handledBy === value ? '#1989fa' : ''
									" :class="{ avtive: main.queryInfo.handledBy === value }" />
						</van-grid>
					</div>
				</van-action-sheet>
				<van-row class="queryList peopleName">
					<van-col span="6">经办人员</van-col>
					<van-col span="14">
						<van-field readonly v-model="main.queryInfo.handledBy" placeholder="经办人员姓名" clearable
							@update:model-value="delHandledBy" @click-input="main.showHandledByActionSheet = true" />
					</van-col>
					<van-col span="4" @click="handleFilter('handler')">
						<van-icon name="search" />
						查询
					</van-col>
				</van-row>

				<van-row class="queryList peopleTotalCost">
					<van-col span="6">人员费用</van-col>
					<van-col span="12">
						<span class="cost">
							¥ {{ main.queryInfo.peopleCost.toFixed(2) }}
						</span>
					</van-col>
					<van-col span="6" @click="clearQuery">
						<van-icon name="replay" />
						重置查询
					</van-col>
				</van-row>
			</van-collapse-item>
		</van-collapse>

		<van-row class="total-travel-count">
			<van-col span="12">
				共
				<span>{{ main.UnreimbursedList.length }}</span>
				条
			</van-col>
			<van-col span="12">
				共
				<span>¥{{ calcTravelTotalCost() }}</span>
				元
			</van-col>
		</van-row>

		<van-empty image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png" image-size="80"
			description="暂无数据" v-if="main.UnreimbursedList.length === 0 && !main.loading" />

		<Card v-for="(item, index) in main.UnreimbursedList" :key="item.id" :border="false" class="card">
			<template #header>
				<van-row class="header">
					<van-col span="1">
						<span>{{ index + 1 }}</span>
					</van-col>
					<van-col span="17">
						<van-text-ellipsis rows="2" :content="item.travelReason"
							style="user-select: auto; -webkit-user-select: auto" />
					</van-col>
					<van-col span="6" class="header-right">
						{{ item.travelDate }}
					</van-col>
				</van-row>
			</template>
			<template #body>
				<van-row class="body body-id">
					<van-col span="4">编号</van-col>
					<van-col span="12">
						<van-text-ellipsis rows="1" :content="item.id" />
					</van-col>
					<van-col span="8">
						<van-button round plain hairline type="default" size="mini" block icon="delete-o"
							@click="deleteRecord(item, index)">
							删除
						</van-button>
						<van-button round plain hairline type="success" size="mini" block icon="completed-o"
							@click="reimbRecord(item, index)">
							核销
						</van-button>
					</van-col>
				</van-row>
				<van-row class="body">
					<van-col span="4">出差地址</van-col>
					<van-col span="20">{{ item.travelAddress }}</van-col>
				</van-row>
				<van-row class="body">
					<van-col span="4">出差人员</van-col>
					<van-col span="20">
						<van-tag plain type="primary" class="body-name_tag" v-for="people in item.travelPeople"
							:key="people.name">
							{{ people.name }}¥{{ people.myTravelExpenses }}
						</van-tag>
					</van-col>
				</van-row>
				<van-row class="body">
					<van-col span="4">经办人员</van-col>
					<van-col span="20">
						<van-tag plain class="body-name_tag">
							{{ item.handledBy || "未定义" }}
						</van-tag>
					</van-col>
				</van-row>
				<van-row class="body">
					<van-col span="4">公务用车</van-col>
					<van-col span="20">
						<van-space align="center" v-if="item.officialCars">
							<van-icon name="passed" color="#5ac725" />
							<span>是</span>
						</van-space>
						<van-space align="center" v-else>
							<van-icon name="close" color="#ee0a24" />
							<span>否</span>
						</van-space>
					</van-col>
				</van-row>
				<van-row class="body">
					<van-col span="4">是否用餐</van-col>
					<van-col span="20">
						<van-row v-for="mealss in item.travelPeople" :style="`margin: ${usePxToVwView(2)} 0`">
							<van-col span="4">{{ mealss.name }}</van-col>
							<van-col span="20">
								<van-checkbox-group :model-value="mealss.mealsSelected" direction="horizontal">
									<van-checkbox :name="item.id" v-for="item in haveMeals" checked-color="#19be6b">
										{{ item.label }}
									</van-checkbox>
								</van-checkbox-group>
							</van-col>
						</van-row>
					</van-col>
				</van-row>
				<van-row class="body" v-if="item.notes">
					<van-col span="4">备注信息</van-col>
					<van-col span="20">
						{{ item.notes }}
					</van-col>
				</van-row>
			</template>
			<template #footer>
				<van-row class="footer">
					<van-col span="18" class="footer-createDate">
						{{ item.createDate }}
					</van-col>
					<van-col span="6" class="footer-totalCost">
						<span>¥{{ item.travelExpenses }}</span>
					</van-col>
				</van-row>
			</template>
		</Card>
	</van-pull-refresh>
</template>
<script setup lang="ts">
import { defineAsyncComponent, reactive, onMounted } from "vue"
import UnreimbursedClass from "./Unreimbursed.ts"
import * as indexedDB from "@/utility/indexedDB"
import { DB } from "@/assets/global"
import { haveMeals, TTravelInfo } from "@/pages/AddTravelRecord/AddTravelRecord"
const Card = defineAsyncComponent(() => import("@components/dataView/Card.vue"))
import usePxToVwView from "@hooks/usePxTransform"
import {
	showConfirmDialog,
	showFailToast,
	showSuccessToast,
	showToast,
} from "vant"
import dayjs from "dayjs"
import isBetween from "dayjs/plugin/isBetween"
dayjs.extend(isBetween)
import TravelRecordLibraryStore from "@/store/TravelRecordLibraryStore.ts"
import _ from "lodash"

// 初始化
const main = reactive(new UnreimbursedClass())
const store = TravelRecordLibraryStore()

// 统一筛选控制函数
const handleFilter = (type: "date" | "people" | "handler") => {
	switch (type) {
		case "date":
			if (main.queryInfo.travelDateRange.length < 2) {
				showToast({ message: "请选择日期范围", position: "top" })
				return
			}
			break
		case "people":
			if (main.queryInfo.peopleName.trim() === "") {
				showToast({ message: "请输入人员姓名", position: "top" })
				return
			}
			break
		case "handler":
			if (main.queryInfo.handledBy === "") {
				showToast({ message: "请选择处理人", position: "top" })
				return
			}
			break
	}

	applyAllFilters()
	showToast({ message: "筛选成功", position: "top" })
}

/**
 * 获取原始数据并初始化
 */
const autoGetDBUnreimbursedList = async () => {
	try {
		main.loading = true
		const result: TTravelInfo[] = await indexedDB.queryAllByIndex(
			DB.store.TravelRecord.name,
			"isReimbursed",
			0
		)

		// 初始化显示数据
		main.UnreimbursedList = result.map(list => ({
			...list,
			travelPeople: Array.from(list.travelPeople),
		}))

		// 保存原始数据
		store.originalUnreimbursedList = _.cloneDeep(main.UnreimbursedList)

		// 默认按降序排序
		queryTravelDateSort()
	} catch (error) {
		console.error("获取未核销记录失败:", error)
		showFailToast("获取数据失败")
	} finally {
		main.loading = false
	}
}

/**
 * 应用所有筛选条件
 */
const applyAllFilters = () => {
	let filtered = [...store.originalUnreimbursedList]

	// 1. 处理人筛选
	if (main.queryInfo.handledBy) {
		filtered = filtered.filter(
			item => item.handledBy === main.queryInfo.handledBy
		)
	}

	// 2. 日期范围筛选
	if (main.queryInfo.travelDateRange.length === 2) {
		const [start, end] = main.queryInfo.travelDateRange
		filtered = filtered.filter(item =>
			dayjs(item.travelDate).isBetween(start, end, null, "[]")
		)
	}

	// 3. 人员筛选
	if (main.queryInfo.peopleName.trim()) {
		filtered = filtered.filter(item =>
			item.travelPeople.some(p => p.name === main.queryInfo.peopleName)
		)
	}

	// 应用筛选结果
	main.UnreimbursedList = filtered.map(item => ({
		...item,
		travelPeople: Array.from(item.travelPeople),
	}))

	// 筛选后排序
	queryTravelDateSort()

	// 计算费用
	clacPeopleCost()

	showToast({ message: "筛选成功", position: "top" })
}

/**
 * 清空所有查询条件
 */
const clearQuery = async () => {
	main.queryInfo = new UnreimbursedClass().queryInfo
	await autoGetDBUnreimbursedList()
	showSuccessToast("查询已清空")
}

/**
 * 计算人员费用
 */
const clacPeopleCost = () => {
	main.queryInfo.peopleCost = 0
	if (!main.queryInfo.peopleName) return

	main.UnreimbursedList.forEach(item => {
		item.travelPeople.forEach(people => {
			if (people.name === main.queryInfo.peopleName) {
				main.queryInfo.peopleCost += Number(people.myTravelExpenses) || 0
			}
		})
	})
}

/**
 * 选择处理人
 */
const selectHandledBy = (people: string) => {
	main.queryInfo.handledBy = main.queryInfo.handledBy === people ? "" : people
	main.showHandledByActionSheet = false
	applyAllFilters()
}

/**
 * 选择出差人员
 */
const selectTravelPeople = (people: string) => {
	main.queryInfo.peopleName = main.queryInfo.peopleName === people ? "" : people
	main.showTravelPeopleActionSheet = false
	applyAllFilters()
}

/**
 * 清除人员查询
 */
const delPeopleName = (value: string) => {
	if (value === "") {
		main.queryInfo.peopleName = ""
		applyAllFilters()
	}
}

/**
 * 清除处理人查询
 */
const delHandledBy = delPeopleName

/**
 * 日期范围确认
 */
const onCalendarConfirm = (values: Date[]) => {
	const [start, end] = values
	main.queryInfo.travelDateRange = [
		dayjs(start).format("YYYY-MM-DD"),
		dayjs(end).format("YYYY-MM-DD"),
	]
	main.queryInfo.travelDateRangeText =
		dayjs(start).format("YYYY-MM-DD") + "~" + dayjs(end).format("YYYY-MM-DD")
	main.queryInfo.showCalendar = false
	applyAllFilters()
}

/**
 * 清除日期范围
 */
const clearTravelDateRange = (e: Event) => {
	e.stopPropagation()
	main.queryInfo.travelDateRange = []
	main.queryInfo.travelDateRangeText = ""
	applyAllFilters()
}

/**
 * 按出差日期排序
 */
const queryTravelDateSort = () => {
	main.UnreimbursedList.sort((a: TTravelInfo, b: TTravelInfo) => {
		return main.queryInfo.travelDateSort
			? dayjs(a.travelDate).diff(b.travelDate) // 升序
			: dayjs(b.travelDate).diff(a.travelDate) // 降序
	})
}

/**
 * 核销记录
 */
const reimbRecord = (record: TTravelInfo, index: number) => {
	showConfirmDialog({
		title: "核销",
		message: `确定核销【${record.travelDate}】前往【${record.travelAddress}】的记录吗?`,
	})
		.then(async () => {
			const data = _.cloneDeep(record)
			data.isReimbursed = 1
			const result = await indexedDB.update(DB.store.TravelRecord.name, data)
			if (result) {
				showSuccessToast(`核销成功`)
				main.UnreimbursedList.splice(index, 1)
				// 更新原始数据
				// await autoGetDBUnreimbursedList()
			} else {
				showFailToast("操作失败")
			}
		})
		.catch(() => {
			/* 取消操作 */
		})
}

/**
 * 删除记录
 */
const deleteRecord = async (record: TTravelInfo, index: number) => {
	showConfirmDialog({
		title: "删除",
		message: `确定删除【${record.travelDate}】前往【${record.travelAddress}】的记录吗?`,
	})
		.then(async () => {
			const result = await indexedDB.remove(
				DB.store.TravelRecord.name,
				record.id
			)
			if (!result) {
				showSuccessToast(`删除成功`)
				main.UnreimbursedList.splice(index, 1)
				// 更新原始数据
				// await autoGetDBUnreimbursedList()
			} else {
				showFailToast("操作失败")
			}
		})
		.catch(() => {
			/* 取消操作 */
		})
}

/**
 * 计算出差总费用
 */
const calcTravelTotalCost = () => {
	return main.UnreimbursedList.reduce(
		(sum, it) => sum + Number(it.travelExpenses),
		0
	)
}

/**
 * 下拉刷新
 */
const onRefresh = () => {
	autoGetDBUnreimbursedList().then(() => {
		main.pullRefresh = false
		showToast({
			message: "刷新成功",
			position: "top",
		})
	})
}

// 初始化加载数据
onMounted(() => {
	autoGetDBUnreimbursedList()
})
</script>

<style scoped lang="scss">
@mixin flex {
	display: flex;
	justify-content: start;
	align-items: center;
}

::v-deep(.van-popup--bottom) {
	height: 65%;
}

.action-sheet-content {

	padding: 16px 16px 60px;

	::v-deep(.van-grid-item__text) {
		margin: auto;
	}

	.avtive {
		::v-deep(.van-grid-item__content) {
			border: 1px solid #1989fa;
		}

		::v-deep(.van-grid-item__text) {
			color: #1989fa;
		}
	}
}

.total-travel-count {
	background-color: white;
	padding: 10px 10px 15px;
	color: $font-content-color;
	font-size: 10px;

	span {
		font-size: 12px;
	}

	:first-child {
		span {
			color: $font-main-color;
		}
	}

	:last-child {
		text-align: right;

		span {
			color: $error-color;
		}
	}
}

.queryList {
	padding: 10px 0;

	.van-col:nth-child(2) {
		span {
			color: #2979ff;
		}
	}

	.van-col:nth-child(3) {
		text-align: right;
	}

	&.peopleTotalCost {
		.cost {
			color: $error-color !important;
		}
	}

	&.travelDateRange {
		.close {
			margin-left: 10px;
		}

		::v-deep(.van-collapse-item__content) {
			color: #333333;
		}
	}

	&.peopleName {
		.van-field {
			padding: 0px;
		}
	}
}

.card {
	color: $font-content-color;
	margin: 10px 0px !important;

	.header {
		.van-col:first-child {
			margin: auto;

			span {
				display: block;
				width: 15px;
				height: 15px;
				color: #ffffff;
				background-color: #2979ff;
				font-size: 10px;
				text-align: center;
				line-height: 15px;
				border-radius: 2px;
			}
		}

		.van-col:nth-child(2) {
			padding-left: 10px;
			margin: auto;
		}

		&-right {
			text-align: right;
			margin: auto;
		}
	}

	.body {
		margin: 10px 0;

		&-id {
			.van-col:nth-child(2) {
				overflow: hidden;
				text-overflow: ellipsis;
				margin: auto;
			}

			.van-col:nth-child(3) {
				@include flex();
				justify-content: end;
			}
		}

		&-name_tag {
			margin-right: 2px;
			padding: 2px 4px;
		}

		.van-col:nth-child(1) {
			text-align-last: justify;
			margin: auto;
		}

		.van-col:nth-child(2) {
			padding-left: 20px;
			margin: auto;
		}
	}

	.footer {
		.footer-createDate {
			display: flex;
			align-items: center;
		}

		.footer-totalCost {
			color: $error-color;
			text-align: right;
			font-size: 18px;

			.avgCose {
				font-size: 12px;
			}
		}
	}
}

::v-deep(.van-text-ellipsis) {
	line-height: 1.2;
}

.van-pull-refresh {
	// 解决下拉内容冲突下拉刷新事件。
	height: calc(100vh - 100px) !important;
	overflow: auto !important;
}
</style>
